<template>
  <div v-loading="loading">
    <!-- 左侧树图 -->
    <header class="tree-header">
      <el-input v-model="filterText" clearable placeholder="请输入关键字" class="mr-10px mb-10px" />
      <!-- <el-popover placement="bottom">
        <template #reference>
          <el-button type="primary" :icon="Plus" circle />
        </template>
<div class="operation-list">
  <p @click="append"><el-icon>
      <FolderAdd />
    </el-icon>新建目录</p>
  <p @click="createTestScene"><el-icon>
      <Cpu />
    </el-icon>新建测试场景</p>
</div>
</el-popover> -->
    </header>
    <el-tree :data="treeData" :allow-drop="allowDrop" :allow-drag="allowDrag" draggable default-expand-all node-key="id"
      @node-drop="handleDrop" :expand-on-click-node="false" :filter-node-method="filterNode" :props="defaultProps"
      :indent="22" @node-click="handleNodeClick" class="tree-com" ref="treeRef">
      <template #default="{ node, data }">
        <span class="custom-tree-node">
          <!-- 项目、模块目录 -->
          <span v-if="['目录'].includes(data.tag)" style="display: flex; align-items: center">
            <span @click.stop="node.expanded = !node.expanded">
              <el-icon v-if="node.expanded" class="case-icon" size="16">
                <FolderOpened />
              </el-icon>
              <el-icon v-else class="case-icon" size="16">
                <Folder />
              </el-icon>
            </span>
            <small>{{ node.label }}<span class="ml-5px" v-if="data.parentId != 0">({{ sceneCount[data.id] || 0
                }})</span></small>
          </span>
          <span v-if="['测试场景'].includes(data.tag)" style="display: flex; align-items: center"
            :class="{ current: defaultId == data.id }">
            <img src="@/assets/svgs/scene.svg" class="case-icon" />
            <small>{{ node.label }}</small>
          </span>
          <span class="operation">
            <el-popover class="operation-popover" v-if="popoverVisible" @before-leave="hidePopver">
              <template #reference>
                <el-icon>
                  <MoreFilled />
                </el-icon>
              </template>
              <div class="operation-list">
                <p @click.stop="append(data)" v-if="data.tag == '目录'"><el-icon>
                    <FolderAdd />
                  </el-icon> 新建子目录 </p>
                <p @click.stop="createTestScene(data)" v-if="data.tag == '目录'"><el-icon>
                    <FolderAdd />
                  </el-icon> 新建测试场景 </p>
                <p @click.stop="edit(data)" v-if="data.tag == '目录'"> <el-icon>
                    <Edit />
                  </el-icon>重命名</p>
                <p @click.stop="remove(data)" v-if="data.parentId != 0"><el-icon>
                    <Remove />
                  </el-icon> 删除 </p>
              </div>
            </el-popover>
          </span>
        </span>
      </template>
    </el-tree>
  </div>

</template>

<script setup lang="ts">
import * as SceneApi from '@/api/scene'
import { MoreFilled, Plus, FolderOpened, Folder, Edit, Remove, FolderAdd } from '@element-plus/icons-vue'
import type Node from 'element-plus/es/components/tree/src/model/node'
import type { AllowDropType } from 'element-plus/es/components/tree/src/tree.type'
import { useAppStore } from '@/store/modules/app'
import { propTypes } from '@/utils/propTypes'
import { findNodeByParams, findAndModifyNode } from '@/utils/tree'
import { useDebugStore } from '@/store/modules/debug'
const appStore = useAppStore()
const debugStore = useDebugStore()
const projectId = computed(() => appStore.getSelectProject)
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const treeRef = ref()
const filterText = ref('')
const emit = defineEmits(['add-directory', 'edit-directory', 'create-scene', 'node-click', 'delete-node', 'edit-scene'])
const popoverVisible = ref(true)
const defaultId = ref()
const defaultProps = {
  children: 'children',
  label: 'name'
}
const treeData = ref([] as any)
const loading = ref(false)
const sceneCount = ref({} as any)
const props = defineProps({
  currentTabId: propTypes.number.def()
})
/** 当前页面变化，树节点选中更新 */
watch(() => props.currentTabId, () => {
  defaultId.value = props.currentTabId
})
/**
 * 过滤
 * */
const filterNode = (value, data) => {
  if (!value) return true
  return data.name.includes(value)
}
watch(filterText, (val) => {
  treeRef.value!.filter(val)
})
watch(() => projectId.value, () => {
  treeData.value = []
  getTreeData()
  getSceneCount()
})
onMounted(() => {
  if (projectId.value) {
    getTreeData()
    getSceneCount()
  }
})
/**
 * 获取树结构数据
 * */
const getTreeData = async () => {
  loading.value = true
  try {
    let res = await SceneApi.getDicSceneList({ projectId: projectId.value })
    treeData.value = res
    debugStore.setTreeData(res)
  } catch (error) {
    console.log(error)
  } finally {
    loading.value = false
  }
}
const getSceneCount = async () => {
  loading.value = true
  try {
    let res = await SceneApi.getSceneCount({ projectId: projectId.value })
    sceneCount.value = res
  } catch (error) {
    console.log(error)
  } finally {
    loading.value = false
  }
}
/**
 * 节点点击
 * */
const handleNodeClick = async (data) => {
  if (!['测试场景'].includes(data.tag)) {
    defaultId.value = ''
    return
  }
  defaultId.value = data.id
  emit('node-click', treeData.value, data)
}

/** 更新节点后立即定位到某个节点 */
const handleFocusNode = async (info) => {
  try {
    await getTreeData()
    getSceneCount()
    const focusNode = findNodeByParams(treeData.value, info.name, info.tag || '测试场景', info.parentId || info.directoryId)
    focusNode && handleNodeClick(focusNode)
  } catch (error) {
    console.log(error)
  }
}

defineExpose({ handleNodeClick, getTreeData, handleFocusNode })

/**
 * 新增目录
 * */
const append = (data) => {
  emit('add-directory', data)
}
/**
 * 重命名
 * */
const edit = (data) => {
  if (data.tag == '目录') {
    emit('edit-directory', data)
  } else {
    emit('edit-scene', data)
  }
}
/**
 * 删除
 * */
const remove = async (data) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    loading.value = true
    // 发起删除
    if (data.tag == '测试场景') {
      await SceneApi.deleteTestScene({ id: data.id })
    } else if (data.tag == '目录') {
      await SceneApi.deleteSceneDic({ id: data.id })
    }
    message.success(t('common.delSuccess'))
    emit('delete-node', data)
    // 刷新列表
    await getTreeData()
    getSceneCount()
  } catch (error) {
    console.log(error)
  } finally {
    loading.value = false
  }
}
/**
 * 新建测试场景
 * */
const createTestScene = (data) => {
  emit('create-scene', data)
}

/**
 * 避免popover闪现bug
 * */
const hidePopver = () => {
  popoverVisible.value = false
  setTimeout(() => {
    popoverVisible.value = true
  }, 10)
}
/** 拖动树后保存 */
const handleDrop = async (draggingNode: Node, dropNode: Node) => {
  // loading.value = true
  // try {
  //   const treeObj = treeData.value[0]
  //   const isModifySuccess = findAndModifyNode(treeObj, draggingNode.data.id, dropNode.data.id)
  //   if (isModifySuccess) {
  //     await DebugApi.saveApiTree(treeObj)
  //     message.success(t('common.updateSuccess'))
  //   }
  // } catch (error) {
  //   console.log(error)
  // } finally {
  //   loading.value = false
  // }
}
/** 只有目录可以被拖入 */
const allowDrop = (draggingNode: Node, dropNode: Node, type: AllowDropType) => {
  if (dropNode.data.tag == '目录') {
    return true
  }
  return false
}
/** 只有接口可以被拖动 */
const allowDrag = (draggingNode: Node) => {
  if (draggingNode.data.tag == '场景' || draggingNode.data.tag == '目录') {
    return true
  }
  return false
}

</script>

<style lang="scss">
.current {
  display: block;
  background-color: var(--el-color-primary-light-9);
  width: 100%;
  position: relative;
  z-index: 1;

  small {
    color: #5e7ce0;
  }

  &::after {
    position: absolute;
    width: 350%;
    content: "";
    left: -155%;
    height: 100%;
    z-index: -1;
    background-color: var(--el-color-primary-light-9);
  }
}

.case-icon {
  margin: 0px 6px 0px 2px;
}

.tree-header {
  display: flex;
}

.method {
  font-style: normal;
  margin-right: 5px;
  font-size: 12px;
  font-weight: 900;
}

.operation-list {
  p {
    display: flex;
    align-items: center;
    border-bottom: 1px solid #ccc;
    padding-bottom: 10px;
    margin: 0 0 10px 0;
    cursor: pointer;

    .el-icon {
      margin-right: 10px;
    }

    &:last-child {
      border: none;
      margin-bottom: 0;
      padding: 0;
    }
  }
}
</style>
